/**
 * 
 */
package com.gragra.sampling.nonproj.structures.projective;
import java.util.BitSet;
import com.gragra.sampling.PopulationProbabilityAssigner;
import com.gragra.sampling.binary.ConvertSample;
import com.gragra.sampling.nonproj.structures.nonprojective.NonProjDepdTree;
import com.gragra.sampling.sequentialStructure.WordAndTagHolder;
/**
 * @author Christoph Teichmann
 * 10.10.2013
 */
public abstract class ProjectiveDepdTree extends NonProjDepdTree
{
	/**
	 * 
	 * @param wth
	 * @param threads
	 * @param cs
	 */
	public ProjectiveDepdTree(WordAndTagHolder wth, int threads,
			ConvertSample cs)
	{super(wth, threads, cs);}
	/* (non-Javadoc)
	 * @see com.gragra.sampling.nonproj.structures.NonProjDepdTree#makeAllHeadCandidates(int, int, com.gragra.sampling.PopulationProbabilityAssigner)
	 */
	@Override
	protected BitSet makeAllHeadCandidates(int pos, int thread,
			PopulationProbabilityAssigner npa)
	{
		BitSet bs = super.makeAllHeadCandidates(pos, thread, npa);
		int min = -1;
		int max = this.getLength()+1;
		for(int i=0;i<this.getLength()&&i<max;++i)
		{
			int head = this.getHeadPosition(i, thread);
			if(head == -1 || i==pos)
			{continue;}
			if(covers(pos,i,head))
			{
				min = Math.max(min, Math.min(i-1, head-1));
				max = Math.min(max, Math.max(i+1, head+1));
			}
			else
			{
				int from = bs.nextSetBit(Math.min(i, head)+1);
				int to = Math.max(i,head);
				for(int f=from;f<to;f=bs.nextSetBit(f+1))
				{bs.clear(f);}
				i = Math.max(i, head-1);
			}
		}
		for(int i=0;i<=min;++i)
		{bs.clear(i);}
		for(int i=max;i<=this.getLength();++i)
		{bs.clear(i);}
		return bs;
	}
	/**
	 * 
	 * @param pos
	 * @param i
	 * @param head
	 * @return
	 */
	private boolean covers(int pos, int from, int to)
	{
		boolean r = from < pos && to > pos;
		r |= from > pos && to < pos;
		return r;
	}	
}